<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>promise</title>
</head>
<body>
	
<script>

globalB = null
	
function P(fn, n) {

	var deferreds = [], value, state = 'pending'
	this.then = function(onFulfilled) {
		var p = new P(function(resolve) {
			handle({onFulfilled: onFulfilled, resolve: resolve, p: p})
		}, 'bridge')
		return p
	}

	this.n = n

	var that = this
	function handle(deferred) {
		
		if(state === 'pending') {
			console.log('%s -> handle deferreds.push', that.n, state)
			deferreds.push(deferred)
			return
		}
		console.log('%s -> handle invoke onFulfilled, value:', that.n, value, deferred.onFulfilled)
		
		var ret = deferred.onFulfilled(value)
		console.log('%s -> handle invoke bridge ref onFulfilled -> ret',that.n, ret)

		
		var resolveRet = deferred.resolve(ret);
		console.log('%s -> handel invoke bridge ref resolve', that.n, resolveRet)
	}

	function resolve(newValue) {
		// if(newValue === 'resolve')
		// {
		// 	console.log('newValue is resolve return')
		// 	return
		// }
		if(newValue && typeof(newValue) === 'object' && typeof(newValue.then) === 'function') {
			var then = newValue.then
			console.log('%s -> resolve then.call begin',that.n, newValue, deferreds[0].onFulfilled)
			// console.log('%s -> resolve then.call deferreds.length',that.n, deferreds.length)
			var p = then.call(newValue, resolve)
			console.log('%s -> resolve then.call end p',that.n, p)
			return
		}

		console.log('%s -> resolve value: %o',that.n, newValue)
		// console.log('%s -> resolve deferreds', that.n, deferreds)
		state = 'fulfilled'
		value = newValue
		setTimeout(function(){
			deferreds.forEach(function(deferred) {
				handle(deferred)
				console.log('%s -> resolve timeout', that.n)
			})
		}, 0)
		// return 'resolve'
	}
	console.log('%s -> init', that.n)
	fn(resolve)
}

var p = new P(function(resolve) {
	setTimeout(function() {
		resolve('initValue')
	}, 0)
}, 'init')
var b1 = p.then(function(value) {
	console.log('then1 get value=%s', value)
	return new P(function(resolve) {
		console.log('then async ivnoke')
		setTimeout(function() {
			console.log('then 1 async done')
			resolve('then1Value')

		}, 1000)

		// console.log('then 1 async done')
		// resolve('then1Value')
	},'then1')
})
console.log(b1)
var b2 = b1.then(function(value) {
	console.log('then2 get value: ', value)
	return 'then2'

	// return new P(function(resolve) {
	// 	console.log('then2 async ivnoke')
	// 	setTimeout(function() {
	// 		console.log('then 2 async done')
	// 		resolve('then2Value')

	// 	}, 1000)

	// 	// console.log('then 1 async done')
	// 	// resolve('then1Value')
	// },'then2')
})
console.log(b2)
var b3 = b2.then(function(value){
	console.log('then3 get value', value)
})



</script>
</body>
</html>